﻿// <copyright file="VirtualRegistryEntryStringValue.cs" company="Sinclair Community College">
// Copyright 2010 Sinclair Community College
// </copyright>
// <originalAuthor>Patrick S. Seymour (patrick.seymour@gmail.com)</originalAuthor>

namespace SinclairCC.AppV
{
    using System;

    /// <summary>
    /// This class represents a virtual registry entry that contains a string value.
    /// </summary>
    internal class VirtualRegistryEntryStringValue : VirtualRegistryEntryValue
    {
        /// <summary>
        /// The total number of intermediate-form strings contained within the actual
        /// value data string.
        /// </summary>
        private int offsetCount;

        /// <summary>
        /// An array of the relative byte offsets from the beginning of the actual string.
        /// </summary>
        /// <remarks>
        /// These offsets are for the intermediate form strings. These offset locations can be
        /// jumped to and replaced with the actual parsed string; the end of the intermediate string
        /// can be found by following the virtual variable (in the form of %XXX%) until the ending
        /// percent character.
        /// </remarks>
        private int[] offsets;

        /// <summary>
        /// Initializes a new instance of the VirtualRegistryEntryStringValue class.
        /// </summary>
        /// <param name="rawData">
        /// The raw data registry data contained in the CP file.
        /// </param>
        public VirtualRegistryEntryStringValue(byte[] rawData)
            : base(rawData)
        {
            this.offsetCount = 0;
            this.offsets = new int[this.offsetCount];
        }

        /// <summary>
        /// Gets the total number of intermediate-form strings contained within the actual
        /// value data string.
        /// </summary>
        public int OffsetCount
        {
            get { return this.offsetCount; }
        }

        /// <summary>
        /// Creates a string representation of the registry value.
        /// </summary>
        /// <returns>
        /// Returns a string representation of the registry value.
        /// </returns>
        public override string ToString()
        {
            ushort marker = 0;
            if (this.RawValue.Length >= 4)
            {
                marker = BitConverter.ToUInt16(this.RawValue, 0);
            }

            if (marker == 0x0101)
            {
                this.offsetCount = BitConverter.ToInt32(this.RawValue, 2);
                this.offsets = new int[this.offsetCount];
                int i = 0;
                for (i = 6; i < (6 + (4 * this.offsetCount)); i += 4)
                {
                    this.offsets[(i - 6) / 4] = BitConverter.ToInt32(this.RawValue, i);
                }

                return System.Text.Encoding.Unicode.GetString(this.RawValue, i, this.RawValue.Length - i - 2);
            }
            else
            {
                return System.Text.Encoding.Unicode.GetString(this.RawValue, 0, this.RawValue.Length - 2);
            }
        }
    }
}
